<?php
Namespace Cyfy\Modules\Menu;

/**
 * Class for menu navigations.
 *
 * @version 0.1
 * @author Dandelion
 */ 
class Menu extends \Cyfy\Translatable
{   
    /**
     * Whether to show not active menu parts. Usefull when there is a JS template.
     * @var bool
     */
    static $showInactive = false; 
    
    
    /**
     * Menus cache
     * @var array
     */
    static private $menus = array();
    
    
    /**
     * Add an item to menu.
     * @param string Title of the item
     * @param string Link link
     * @param int    Menu ID
     * @param string Language. Default if not selected.
     */
	static public function addItem($title, $link, $menu, $language = '')
	{
        if($language == ''){
            $language = \Cyfy\Language :: getActive(); 
        }
        
        $values = array(
            'language' => $language,
            'mid' => $menu,
            'name' => $title,
            'link' => $link
        );
		return \dibi :: query("INSERT INTO [:cyfy:Menu-items] %v", $values);
	}
	
    /**
     * Removes an item when we know link. MenuID is optional.
     *
     * @param string Link
     * @param int    Menu ID
     */
	static function removeItemByLink($link, $menu = 0)
	{
		if(!$menu)
		{
			return \dibi :: query("DELETE FROM [:cyfy:Menu-items] WHERE [link] = %s", $link);
		}
        return \dibi :: query("DELETE FROM [:cyfy:Menu-items] WHERE [link] = %s", $link, " AND mid = %i", $menu);
	}
	
    /**
     * Updates links in menus.
     *
     * @param string old link
     * @param string new link
     * @return bool
     */
	static function updateLinks($oldLink, $newLink)
	{
		return \dibi :: query("UPDATE [:cyfy:Menu-items] SET [link] = %s", $newLink, " WHERE [link] = %s", $oldLink);
	}
    
    
    /**
     * Returns list of menus as an associative array sorted by name.
     * @return array Menus
     */
    static public function getAll()
    {
        // if loaded
        if(count(self :: $menus))
        {
            return self :: $menus;
        }
        
        // else get from db
        $result = \dibi :: query("SELECT [mid], [name] FROM [:cyfy:Menu-menus] ORDER BY [name] ASC");
        
        // no menus found
        if(count($result) == 0)
        {
            return false;
        }
        
		self :: $menus = $result -> fetchPairs('mid', 'name');
        return self :: $menus;
    }
    
    /**
     * Sets 'parents' active when loading a menu
     * @param array Menu items
     * @param int Current item
     * @param int Depth
     * @return array Fixed menu items.
     */
	static private function setParentsActive($mis, $current, $depth){
		for($i=($current-1); $i>=0; $i--)
		{
			if($mis[$i]["depth"] < $depth)
			{
				$mis[$i]["active"]=true;
				$mis = self :: setParentsActive($mis, $i, $mis[$i]["depth"]);
				break;
			}
		}
		return $mis;
	}

    /**
     * Loads a menu by name.
     *
     * @param string Menu name
     * @return HTML cotnent
     */
	static public function load($name)
	{
		// get data from mysql
		$menu = \dibi :: query("SELECT * FROM [:cyfy:Menu-menus] WHERE code = %s LIMIT 1", $name) -> fetch();

		$resulti = \dibi :: query("SELECT * FROM [:cyfy:Menu-items] WHERE [mid] = %i", $menu["mid"]," AND [language] = %s ORDER BY [weight]", \Cyfy\Language :: getActive());
 
		// if no items
		if(count($resulti) == 0)
		{
			return self :: t(10);  
		}
      	
        // menu items
		$mis = array(); 
		$i=0;
		$lastDepth = 0;
		
		// load items from mysql
		foreach($resulti as $mi)
		{
			$mis[$i] = $mi;
			// if active
			if($mi["link"]){
				if(strpos(\Cyfy\Cyfy ::  $query, $mi["link"]) !== false){
					$mis[$i]["active"]=true;
					$mis = self :: setParentsActive($mis, $i, $mi["depth"]);
				}
			}
			$i++;
		}
		
		$menuContent = "<h3 class=\"menu_header menu_{$menu["code"]}_header\">". $menu["name"] . "</h3>\n";
		$menuContent .= "<ul class=\"menu menu_{$menu["code"]}\">\n";
		
		// creating list
		$first = true;
		foreach($mis as $mi)
		{
            // show?
            if(!self :: $showInactive && $mi["depth"] != 0 && $mi["depth"] != $lastDepth && !$lastActivity) continue;
			$classes = "menu_" . $menu["code"] . "_". strtr($mi["link"], "/:", "__");
			if($first){
				$classes .= " first";
				$first = false;
			}
			if($mi["active"]){
				$classes .= " active";
			}
			$classes .= " depth_" . $mi["depth"];
			// operating with depth
			$depth = $mi["depth"];
            while($depth != $lastDepth){
				if($depth > $lastDepth){
					$first = false;
					$menuContent .= " <li class=\"empty{$lastActivity}  depth_" . $depth ."\"><ul>\n";
					$depth--;
				}
				if($depth < $lastDepth){
					$menuContent .= " </ul></li>\n";
					$depth++;
				}
			}
			$lastActivity = ($mi["active"]) ? " open" : "";
			$lastDepth = $mi["depth"];
      
			// if link doesn't start with http://, add absolute prefix
			if(preg_match("/http:\/\//", $mi["link"]))
			{
				$url = $mi["link"];
			}
			else
			{
				$url = \Cyfy\Cyfy ::  getPath($mi["link"]);
			}
			// finally, creating the <li> element
			$menuContent .= "	<li class=\"{$classes}\"><a href=\"{$url}\" title=\"{$mi["description"]}\">{$mi["name"]}</a></li>\n";
		}
		// if last depth > 0, finish it...
		while($lastDepth > 0){
			$menuContent .= " </ul></li>\n";
			$lastDepth--;
		}
		$menuContent .= "</ul>\n";
	    return $menuContent;
	}
}
